home *** CD-ROM | disk | FTP | other *** search
/ Cream of the Crop 1 / Cream of the Crop 1.iso / PROGRAM / DDJ0192.ARJ / DSP.ASC < prev    next >
Text File  |  1991-11-21  |  26KB  |  687 lines

  1. _PARALLEL DSP FOR DESIGNING ADAPTIVE FILTERS_
  2. by Daniel Chen
  3.  
  4.  
  5.  
  6. [LISTING NEW]
  7.  
  8. /******* PSEUDO C CODE FOR CASCADE ADAPTIVE FILTER #1 *******/
  9. /* Initialization */
  10.     xptr = &x[0];
  11.     wptr = &w[0];
  12.  
  13.     for (i=0;i<N1;i++){
  14.     *xptr++ = 0.0;
  15.     *wptr++ = 0.0;
  16.     }
  17. /*         N1-1
  18. *   Compute  y1 = SUM w[i] * x[i]
  19. *      i=0
  20. */
  21.     xptr = &x[0];
  22.     wptr = &w[0];
  23.     input(x);              /* input x from A/D converter */
  24.     *xptr = x;
  25.     input (d);             /* input d from A/D converter */
  26.  
  27.     for (i=0;i<N1;i++)
  28.     y1 += *xptr++ * *wptr++;
  29. /* Compute  y = y1 + y2 + y3 + y4 */
  30.     receive(y2,y3,y4);         /* receive y2, y3, y4 form processor 2, 3, 4 */
  31.     y = y1 + y2 + y3 + y4;
  32. /* Compute error signal e */
  33.     e = d - y;
  34.     output(y);          /* output y to D/A converter */
  35.     pass(e);            /* pass e to processor 2, 3, 4 */
  36. /* Update filter weights w[] */
  37.     xptr = &x[N1-1];
  38.     wptr = &w[N1-1];
  39.     pass (*xptr);       /* pass x(n-N1) to processor #2 */
  40.     for (i=N1;i>0;i--){
  41.     *wptr-- += mu * e *xptr--;
  42.     *(xptr+1) = *xptr;  /* delayed tap is implemented in circular buffer */
  43.     }
  44.  
  45.  
  46. [LISTING TWO]
  47.  
  48. /******* PSEUDO C CODE FOR CASCADE ADAPTIVE FILTER #2 *******/
  49. /* Initialization */
  50.     xptr = &x[0];
  51.     wptr = &w[0];
  52.     for (i=0;i<N2;i++){
  53.     *xptr++ = 0.0;
  54.     *wptr++ = 0.0;
  55.     }
  56. /*                N2-1
  57. *   Compute  y2 = SUM w[i] * x[i]
  58. *         i=0
  59. */
  60.     xptr = &x[0];
  61.     wptr = &w[0];
  62.     receive(x);          /* receive x(n-N1) from processor #1 */
  63.     *xptr = x;
  64.     for (i=0;i<N2;i++)
  65.     y2 += *xptr++ * *wptr++;
  66. /* pass y2 and receive e */
  67.     pass(y2);           /* pass y2 to processor #1 */
  68.     receive(e);         /* receive e(n) form processor #1 */
  69. /* Update filter weights w[] */
  70.     xptr = &x[N2-1];
  71.     wptr = &w[N2-1];
  72.     pass (*xptr);       /* pass x(n-N1-N2) to processor #3 */
  73.     for (i=N2;i>0;i--){
  74.     *wptr-- += mu * e *xptr--;
  75.     *(xptr+1) = *xptr;  /* delayed tap is implemented in circular buffer */
  76.     }
  77.  
  78.  
  79. [LISTING THREE]
  80.  
  81. /****** PSEUDO C CODE FOR CASCADE ADAPTIVE FILTER #3 ******/
  82. /* Initialization */
  83.     xptr = &x[0];
  84.     wptr = &w[0];
  85.  
  86.     for (i=0;i<N3;i++){
  87.     *xptr++ = 0.0;
  88.     *wptr++ = 0.0;
  89.     }
  90. /*            N3-1
  91. *   Compute  y3 = SUM w[i] * x[i]
  92. *         i=0
  93. */
  94.     xptr = &x[0];
  95.     wptr = &w[0];
  96.     receive(x);          /* receive x(n-N1-N2) from processor #2 */
  97.     *xptr = x;
  98.  
  99.     for (i=0;i<N3;i++)
  100.     y3 += *xptr++ * *wptr++;
  101. /* pass y3 and receive e */
  102.     pass(y3);           /* pass y3 to processor #1 */
  103.     receive(e);         /* receive e(n) form processor #1 */
  104.  
  105. /* Update filter weights w[] */
  106.     xptr = &x[N3-1];
  107.     wptr = &w[N3-1];
  108.     pass (*xptr);       /* pass x(n-N1-N2-N3) to processor #4 */
  109.     for (i=N3;i>0;i--){
  110.     *wptr-- += mu * e *xptr--;
  111.     *(xptr+1) = *xptr;  /* delayed tap is implemented
  112.                    in circular buffer          */
  113.     }
  114.  
  115.  
  116. [LISTING FOUR]
  117.  
  118. /****** PSEUDO C CODE FOR CASCADE ADAPTIVE FILTER #4 ******/
  119. /* Initialization */
  120.     xptr = &x[0];
  121.     wptr = &w[0];
  122.  
  123.     for (i=0;i<N4;i++){
  124.     *xptr++ = 0.0;
  125.     *wptr++ = 0.0;
  126.     }
  127. /*               N4-1
  128. *   Compute  y4 = SUM w[i] * x[i]
  129. *         i=0
  130. */
  131.     xptr = &x[0];
  132.     wptr = &w[0];
  133.     receive(x);          /* receive x(n-N1-N2-N3) from processor #3 */
  134.     *xptr = x;
  135.  
  136.     for (i=0;i<N4;i++)
  137.     y4 += *xptr++ * *wptr++;
  138. /* pass y4 and receive e */
  139.     pass(y4);           /* pass y4 to processor #1 */
  140.     receive(e);         /* receive e(n) form processor #1 */
  141.  
  142. /* Update filter weights w[] */
  143.     xptr = &x[N4-1];
  144.     wptr = &w[N4-1];
  145.     for (i=N3;i>0;i--){
  146.     *wptr-- += mu * e *xptr--;
  147.     *(xptr+1) = *xptr;  /* delayed tap is implemented
  148.                    in circular buffer          */
  149.     }
  150.  
  151.  
  152. [LISTING FIVE]
  153.  
  154. **********************************************************************
  155. *   CONST.H - This file set up the constant for Cascade TMS320C40
  156. *   Adaptive Filter programs: LMS1.ASM LMS2.ASM LMS3.ASM LMS4.ASM
  157. **********************************************************************
  158. order1      .set    N1             ; filter order for #1 C40
  159. order2      .set    N2             ; filter order for #2 C40
  160. order3      .set    N3             ; filter order for #3 C40
  161. order4      .set    N4             ; filter order for #4 C40
  162. mu      .set    0.01           ; step size
  163. io_port     .set    0100081h           ; data I/O comm port addr for d, x, & y
  164. C40_1_2     .set    0100041h           ; comm port address from #1 to #2 C40
  165. C40_1_3     .set    0100051h           ; comm port address from #1 to #3 C40
  166. C40_1_4     .set    0100061h           ; comm port address from #1 to #4 C40
  167. C40_2_1     .set    0100071h           ; comm port address from #2 to #1 C40
  168. C40_2_3     .set    0100061h           ; comm port address from #2 to #3 C40
  169. C40_2_4     .set    0100051h           ; comm port address from #2 to #4 C40
  170. C40_3_1     .set    0100081h           ; comm port address from #3 to #1 C40
  171. C40_3_2     .set    0100071h           ; comm port address from #3 to #2 C40
  172. C40_3_4     .set    0100061h           ; comm port address from #3 to #4 C40
  173. C40_4_1     .set    0100071h           ; comm port address from #4 to #1 C40
  174. C40_4_2     .set    0100081h           ; comm port address from #4 to #2 C40
  175. C40_4_3     .set    0100091h           ; comm port address from #4 to #3 C40
  176.  
  177.  
  178.  
  179. [LISTING SIX]
  180.  
  181. ******************************************************************
  182. *    LMS1 :  Cascade TMS320C40 adaptive filter #1 Using Transversal
  183. *        Structure and LMS Algorithm, Looped Code
  184. *    Configuration:
  185. *        d(n) --------------------------+
  186. *                       |
  187. *               e(n)        |+
  188. *                 +-----<-----(SUM)
  189. *                 |         |-
  190. *             --------+--------     |
  191. *        x(n) ----|Adaptive Filter|-----+--------> y(n)
  192. *             -----------------
  193. *         +--------<-------+-------<--------+-------<--------+
  194. *         |        |y2(n)       |y3(n)       |y4(n)
  195. *   y(n)<-+   |        |            |            |
  196. *     |  +----+----+      +----+----+      +----+----+  +----+----+
  197. *     +--|TMS320C40|x(n1) |TMS320C40|x(n2) |TMS320C40|x(n3) |TMS320C40|
  198. *   x(n)---->|         |----->|     |----->|     |----->|     |
  199. *     +->|   # 1   |      |   # 2   |      |   # 3   |  |   # 4   |
  200. *     |  +----+----+      +----+----+      +----+----+  +----+----+
  201. *   d(n)--+   |        |            |            |
  202. *         e(n)|        |            |            |
  203. *         +-------->-------+------->--------+------->--------+
  204. *         where n1 = n-N1, n2 = n-N1-N2, and n3 = n-N1-N2-N3
  205. *    Algorithm for processor #1:
  206. *       N1-1
  207. *   y1(n) = SUM w(k)*x(n-k)    k=0,1,2,...,N1-1
  208. *       k=0
  209. *   y(n) = y1(n) + y2(n) + y3(n) + y4(n)
  210. *       e(n) = d(n) - y(n)
  211. *   w(k) = w(k) + u*e(n)*x(n-k) k=0,1,2,...,N1-1
  212. *   where filter order N = N1 + N2 + N3 + N4 and u is the step size mu,
  213. **********************************************************************
  214.         .include "const.h"         ; include the constant definition file
  215.         .sect    "vector"
  216. reset       .word     begin
  217. ;   Initialize pointers and arrays
  218. ;     xptr = &x[0];
  219. ;     wptr = &w[0];
  220. ;     for (i=0;i<N1;i++){
  221. ;     *xptr++ = 0.0;
  222. ;     *wptr++ = 0.0;
  223. ;     }
  224.         .text
  225. begin       .set    $
  226.         LDP     @io_addr           ; set data page
  227.         LDI     0,R2           ; R2 = 0
  228.         LDF     0.0,R1         ; R1 = 0.0
  229.         LDI     @io_addr,AR4       ; set pointer for data I/O
  230.         LDI     @C40addr2,AR5      ; set pointer for #2 C40 comm port
  231.         LDI     @C40addr3,AR6      ; set pointer for #3 C40 comm port
  232.         LDI     @C40addr4,AR7      ; set pointer for #4 C40 comm port
  233.         LDI     @xn_addr,AR0       ; set pointer for x[]
  234.         LDI     @wn_addr,AR1       ; set pointer for w[]
  235.         STI     R2,*-AR5(1)        ; enable #2 C40 comm port
  236.         STI     R2,*-AR6(1)        ; enable #3 C40 comm port
  237.         STI     R2,*-AR7(1)        ; enable #4 C40 comm port
  238.         STF     R1,*+AR5(1)        ; start #2 C40
  239.         RPTS    order1-1
  240.         STF     R1,*AR0++(1)%      ; x[] = 0.
  241.     ||  STF     R1,*AR1++(1)%      ; w[] = 0.
  242.         LDI     order1,BK          ; set up circular buffer
  243. input:
  244. ;   Compute filter output y1(n)
  245. ;     xptr = &x[0];
  246. ;     wptr = &w[0];
  247. ;     input(x);          /* input x from A/D converter */
  248. ;     input (d);          /* input d from A/D converter */
  249. ;     *xptr = x;
  250. ;     for (i=0;i<N1;i++)
  251. ;     y1 += *xptr++ * *wptr++;
  252.         LDI     order1-2,RC
  253.         RPTBD   filter
  254.         LDF     *AR4,R6        ; input x(n)
  255.         LDF     *AR4,R7        ; input d(n)
  256.     ||  STF     R6,*AR0        ; insert x(n) to buffer
  257.         MPYF3   *AR0++(1)%,*AR1++(1)%,R1
  258.     ||  SUBF3   R2,R2,R2           ; R2 = 0.0
  259. filter      MPYF3   *AR0++(1)%,*AR1++(1)%,R1
  260.     ||  ADDF3   R1,R2,R2           ; y1(n) = w[].x[]
  261.         ADDF    R1,R2          ; include last result
  262. ;   compute y(n) signals
  263. ;     receive(y2,y3,y4);    /* receive y2, y3, y4 form processor 2, 3, 4 */
  264. ;     y = y1 + y2 + y3 + y4;
  265.         ADDF    *AR5,R2        ; add y2(n)
  266.         ADDF    *AR6,R2        ; add y3(n)
  267.         ADDF    *AR7,R2        ; add y4(n)
  268. ;   Compute error signal e(n)
  269. ;     e = d - y;
  270. ;     pass(e);            /* pass e to processor 2, 3, 4 */
  271.         SUBF    R2,R7          ; e(n) = d(n) - y(n)
  272.         MPYF    @u,R7          ; R7 = err = e(n) * u
  273. ;   Output y(n) signal and e(n)
  274. ;     output(y);          /* output y to D/A converter */
  275. ;     pass(e);            /* pass e to processor 2, 3, 4 */
  276.         STF     R7,*+AR5(1)        ; send out e(n)
  277.     ||  STF     R7,*+AR6(1)        ; send out e(n)
  278.         STF     R2,*+AR4(1)        ; send out y(n)
  279.     ||  STF     R7,*+AR7(1)        ; send out e(n)
  280. ;   Update weights w(n)
  281. ;     xptr = &x[N1-1];
  282. ;     wptr = &w[N1-1];
  283. ;     pass (*xptr);       /* pass x(n-N1) to processor #2 */
  284. ;     for (i=N1;i>0;i--){
  285. ;     *wptr-- += mu * e *xptr--;
  286. ;     *(xptr+1) = *xptr;      /* delayed tap is implemented
  287. ;                    in circular buffer      */
  288. ;     }
  289.         LDI     order1-3,RC        ; initialize repeat counter
  290.         RPTBD   weight         ; do i = 0, N-3
  291.         MPYF3   R7,*AR0++(1)%,R1   ; R1 = err * x(n)
  292.         ADDF3   R1,*AR1,R2         ; R2 = wi(n) + err * x(n)
  293.         NOP
  294.  
  295.         MPYF3   R7,*AR0++(1)%,R1   ; R1 = err * x(n-i-1)
  296.     ||  STF     R2,*AR1++(1)%      ; update wi(n+1)
  297. weight      ADDF3   R1,*AR1,R2         ; R2 = wi(n) + err * x(n-i)
  298.         LDF     *AR0,R6
  299.     ||  STF     R2,*AR1++(1)%      ; update wi(n+1)
  300.         BD      input          ; delay branch
  301.         MPYF3   R7,*AR0,R1         ; R1 = err * x(n-N+1)
  302.     ||  STF     R6,*+AR5(1)        ; shift x(n-N) to #2 C40
  303.         ADDF3   R1,*AR1,R2         ; R2 = wi(n-N+1) + err * x(n-N+1)
  304.         STF     R2,*AR1++(1)%      ; update last w
  305.  
  306. ;   Define constants
  307. xn      .usect  "buffer",order1
  308. wn      .usect  "coeffs",order1
  309.         .data
  310. io_addr     .word   io_port
  311. C40addr2    .word   C40_1_2
  312. C40addr3    .word   C40_1_3
  313. C40addr4    .word   C40_1_4
  314. xn_addr     .word   xn
  315. wn_addr     .word   wn
  316. u       .float  mu
  317.         .end
  318.  
  319.  
  320.  
  321. [LISTING SEVEN]
  322.  
  323. ******************************************************************
  324. *    LMS2 :  Cascade TMS320C40 adaptive filter #2 Using Transversal
  325. *        Structure and LMS Algorithm, Looped Code
  326. *    Configuration:
  327. *        d(n) --------------------------+
  328. *                       |
  329. *               e(n)        |+
  330. *                 +-----<-----(SUM)
  331. *                 |         |-
  332. *             --------+--------     |
  333. *        x(n) ----|Adaptive Filter|-----+--------> y(n)
  334. *             -----------------
  335. *         +--------<-------+-------<--------+-------<--------+
  336. *         |        |y2(n)       |y3(n)       |y4(n)
  337. *   y(n)<-+   |        |            |            |
  338. *     |  +----+----+      +----+----+      +----+----+  +----+----+
  339. *     +--|TMS320C40|x(n1) |TMS320C40|x(n2) |TMS320C40|x(n3) |TMS320C40|
  340. *   x(n)---->|         |----->|     |----->|     |----->|     |
  341. *     +->|   # 1   |      |   # 2   |      |   # 3   |  |   # 4   |
  342. *     |  +----+----+      +----+----+      +----+----+  +----+----+
  343. *   d(n)--+   |        |            |            |
  344. *         e(n)|        |            |            |
  345. *         +-------->-------+------->--------+------->--------+
  346. *         where n1 = n-N1, n2 = n-N1-N2, and n3 = n-N1-N2-N3
  347. *    Algorithm for processor #2:
  348. *       N2-1
  349. *   y2(n) = SUM w(N1+k)*x(n-N1-k)    k=0,1,2,...,N2-1
  350. *       k=0
  351. *   w(N1+k) = w(N1+k) + u*e(n)*x(n-N1-k) k=0,1,2,...,N2-1
  352. *   where filter order N = N1 + N2 + N3 + N4 and u is the step size mu.
  353. **********************************************************************
  354.         .include "const.h"         ; include the constant definition file
  355.         .sect   "vector"
  356. reset       .word   begin
  357. ;   Initialize pointers and arrays
  358. ;     xptr = &x[0];
  359. ;     wptr = &w[0];
  360. ;     for (i=0;i<N2;i++){
  361. ;     *xptr++ = 0.0;
  362. ;     *wptr++ = 0.0;
  363. ;     }
  364.         .text
  365. begin       .set    $
  366.         LDP     @C40addr1          ; set data page
  367.         LDI     0,R2           ; R2 = 0
  368.         LDF     0.0,R1         ; R1 = 0.0
  369.         LDI     @C40addr1,AR5      ; set pointer for #1 C40 comm port
  370.         LDI     @C40addr3,AR6      ; set pointer for #3 C40 comm port
  371.         LDI     @C40addr4,AR7      ; set pointer for #4 C40 comm port
  372.         LDI     @xn_addr,AR0       ; set pointer for x[]
  373.         LDI     @wn_addr,AR1       ; set pointer for w[]
  374.         STI     R2,*-AR6(1)        ; enable #3 C40 comm port
  375.         STI     R2,*-AR5(1)        ; enable #1 C40 comm port
  376.         STI     R2,*-AR7(1)        ; enable #4 C40 comm port
  377.         STF     R1,*+AR6(1)        ; start #3 C40
  378.         RPTS    order2-1
  379.         STF     R1,*AR0++(1)%      ; x[] = 0.
  380.     ||  STF     R1,*AR1++(1)%      ; w[] = 0.
  381.         LDI     order2,BK       ; set up circular buffer
  382. input:
  383. ;   Compute filter output y(n)
  384. ;     xptr = &x[0];
  385. ;     wptr = &w[0];
  386. ;     receive(x);          /* receive x(n-N1) from processor #1 */
  387. ;     *xptr = x;
  388. ;     for (i=0;i<N2;i++)
  389. ;    y2 += *xptr++ * *wptr++;
  390.         LDI     order2-2,RC
  391.         RPTBD   filter
  392.         LDF     *AR5,R6        ; input x(n)
  393.         STF     R6,*AR0        ; insert x(n) to buffer
  394.         MPYF3   *AR0++(1)%,*AR1++(1)%,R1
  395.     ||  SUBF3   R2,R2,R2           ; R2 = 0.0
  396. filter      MPYF3   *AR0++(1)%,*AR1++(1)%,R1
  397.     ||  ADDF3   R1,R2,R2           ; y2(n) = w[].x[]
  398.         ADDF    R1,R2          ; include last result
  399. ;   Output y2(n) signals
  400. ;     pass(y2);           /* pass y2 to processor #1 */
  401.         STF     R2,*+AR5(1)        ; send y2(n) to #1 C40
  402. ;   Input error signal e(n)
  403. ;     receive(e);         /* receive e(n) form processor #1 */
  404.         LDF     *AR5,R7        ; load e(n) from #1 C40
  405. ;   Update weights w(n)
  406. ;     xptr = &x[N2-1];
  407. ;     wptr = &w[N2-1];
  408. ;     pass (*xptr);       /* pass x(n-N1-N2) to processor #3 */
  409. ;     for (i=N2;i>0;i--){
  410. ;     *wptr-- += mu * e *xptr--;
  411. ;     *(xptr+1) = *xptr;      /* delayed tap is implemented
  412. ;                    in circular buffer      */
  413. ;     }
  414. ;
  415.         LDI     order2-3,RC        ; initialize repeat counter
  416.         RPTBD   weight         ; do i = 0, N2-3
  417.         MPYF3   R7,*AR0++(1)%,R1   ; R1 = err * x(n)
  418.         ADDF3   R1,*AR1,R2         ; R2 = wi(n) + err * x(n)
  419.         NOP
  420.  
  421.         MPYF3   R7,*AR0++(1)%,R1   ; R1 = err * x(n-i-1)
  422.     ||  STF     R2,*AR1++(1)%      ; update wi(n+1)
  423. weight      ADDF3   R1,*AR1,R2         ; R2 = wi(n) + err * x(n-i)
  424.  
  425.         LDF     *AR0,R6
  426.     ||  STF     R2,*AR1++(1)%      ; update wi(n+1)
  427.         BD      input          ; delay branch
  428.         MPYF3   R7,*AR0,R1         ; R1 = err * x(n-N+1)
  429.     ||  STF     R6,*+AR6(1)        ; shift x(n-N) to #3 C40
  430.         ADDF3   R1,*AR1,R2         ; R2 = wi(n-N+1) + err * x(n-N+1)
  431.         STF     R2,*AR1++(1)%      ; update last w
  432.  
  433. ;   Define constants
  434. xn      .usect  "buffer",order2
  435. wn      .usect  "coeffs",order2
  436.         .data
  437. C40addr1    .word   C40_2_1
  438. C40addr3    .word   C40_2_3
  439. C40addr4    .word   C40_2_4
  440. xn_addr     .word   xn
  441. wn_addr     .word   wn
  442.         .end
  443.  
  444.  
  445. [LISTING EIGHT]
  446.  
  447. ******************************************************************
  448. *    LMS3 :  Cascade TMS320C40 adaptive filter #3 Using Transversal
  449. *        Structure and LMS Algorithm, Looped Code
  450. *    Configuration:
  451. *        d(n) --------------------------+
  452. *                       |
  453. *               e(n)        |+
  454. *                 +-----<-----(SUM)
  455. *                 |         |-
  456. *             --------+--------     |
  457. *        x(n) ----|Adaptive Filter|-----+--------> y(n)
  458. *             -----------------
  459. *         +--------<-------+-------<--------+-------<--------+
  460. *         |        |y2(n)       |y3(n)       |y4(n)
  461. *   y(n)<-+   |        |            |            |
  462. *     |  +----+----+      +----+----+      +----+----+  +----+----+
  463. *     +--|TMS320C40|x(n1) |TMS320C40|x(n2) |TMS320C40|x(n3) |TMS320C40|
  464. *   x(n)---->|         |----->|     |----->|     |----->|     |
  465. *     +->|   # 1   |      |   # 2   |      |   # 3   |  |   # 4   |
  466. *     |  +----+----+      +----+----+      +----+----+  +----+----+
  467. *   d(n)--+   |        |            |            |
  468. *         e(n)|        |            |            |
  469. *         +-------->-------+------->--------+------->--------+
  470. *         where n1 = n-N1, n2 = n-N1-N2, and n3 = n-N1-N2-N3
  471. *    Algorithm for processor #3:
  472. *       N3-1
  473. *   y3(n) = SUM w(N1+N2+k)*x(n-N1-N2-k)    k=0,1,2,...,N3-1
  474. *       k=0
  475. *   w(N1+N2+k) = w(N1+N2+k) + u*e(n)*x(n-N1-N2-k) k=0,1,2,...,N3-1
  476. *   where filter order N = N1 + N2 + N3 + N4 and u is the step size mu.
  477. **********************************************************************
  478.         .include "const.h"         ; include the constant definition file
  479.         .sect    "vector"
  480. reset       .word     begin
  481. ;   Initialize pointers and arrays
  482. ;     xptr = &x[0];
  483. ;     wptr = &w[0];
  484. ;     for (i=0;i<N3;i++){
  485. ;     *xptr++ = 0.0;
  486. ;     *wptr++ = 0.0;
  487. ;     }
  488.         .text
  489. begin       .set    $
  490.         LDP     @C40addr1          ; set data page
  491.         LDI     0,R2           ; R2 = 0
  492.         LDF     0.0,R1         ; R1 = 0.0
  493.         LDI     @C40addr1,AR5      ; set pointer for #1 C40 comm port
  494.         LDI     @C40addr2,AR6      ; set pointer for #2 C40 comm port
  495.         LDI     @C40addr4,AR7      ; set pointer for #4 C40 comm port
  496.         LDI     @xn_addr,AR0       ; set pointer for x[]
  497.         LDI     @wn_addr,AR1       ; set pointer for w[]
  498.         STI     R2,*-AR7(1)        ; enable #4 C40 comm port
  499.         STI     R2,*-AR6(1)        ; enable #2 C40 comm port
  500.         STI     R2,*-AR5(1)        ; enable #1 C40 comm port
  501.         STF     R1,*+AR7(1)        ; start #4 C40
  502.         RPTS    order3-1
  503.         STF     R1,*AR0++(1)%      ; x[] = 0.
  504.     ||  STF     R1,*AR1++(1)%      ; w[] = 0.
  505.         LDI     order3,BK          ; set up circular buffer
  506. input:
  507. ;   Compute filter output y(n)
  508. ;     xptr = &x[0];
  509. ;     wptr = &w[0];
  510. ;     receive(x);          /* receive x(n-N1-N2) from processor #2 */
  511. ;     *xptr = x;
  512. ;     for (i=0;i<N3;i++)
  513. ;     y3 += *xptr++ * *wptr++;
  514.         LDI     order3-2,RC
  515.         RPTBD   filter
  516.         LDF     *AR6,R6        ; input x(n)
  517.         STF     R6,*AR0        ; insert x(n) to buffer
  518.         MPYF3   *AR0++(1)%,*AR1++(1)%,R1
  519.     ||  SUBF3   R2,R2,R2           ; R2 = 0.0
  520. filter      MPYF3   *AR0++(1)%,*AR1++(1)%,R1
  521.     ||  ADDF3   R1,R2,R2           ; y3(n) = w[].x[]
  522.         ADDF    R1,R2          ; include last result
  523. ;   Output y2(n) signals
  524. ;     pass(y3);           /* pass y3 to processor #1 */
  525.         STF     R2,*+AR5(1)        ; send y3(n) to #1 C40
  526. ;   Input error signal e(n)
  527. ;     receive(e);         /* receive e(n) form processor #1 */
  528.         LDF     *AR5,R7        ; load e(n) from #1 C40
  529. ;   Update weights w(n)
  530. ;     xptr = &x[N3-1];
  531. ;     wptr = &w[N3-1];
  532. ;     pass (*xptr);       /* pass x(n-N1-N2-N3) to processor #4 */
  533. ;     for (i=N3;i>0;i--){
  534. ;     *wptr-- += mu * e *xptr--;
  535. ;     *(xptr+1) = *xptr;      /* delayed tap is implemented
  536. ;                    in circular buffer      */
  537. ;     }
  538. ;
  539.         LDI     order3-3,RC        ; initialize repeat counter
  540.         RPTBD   weight         ; do i = 0, N3-3
  541.         MPYF3   R7,*AR0++(1)%,R1   ; R1 = err * x(n)
  542.         ADDF3   R1,*AR1,R2         ; R2 = wi(n) + err * x(n)
  543.         NOP
  544.  
  545.         MPYF3   R7,*AR0++(1)%,R1   ; R1 = err * x(n-i-1)
  546.     ||  STF     R2,*AR1++(1)%      ; update wi(n+1)
  547. weight      ADDF3   R1,*AR1,R2         ; R2 = wi(n) + err * x(n-i)
  548.  
  549.         LDF     *AR0,R6
  550.     ||  STF     R2,*AR1++(1)%      ; update wi(n+1)
  551.         BD      input          ; delay branch
  552.         MPYF3   R7,*AR0,R1         ; R1 = err * x(n-N+1)
  553.     ||  STF     R6,*+AR7(1)        ; shift x(n-N) to #4 C40
  554.         ADDF3   R1,*AR1,R2         ; R2 = wi(n-N+1) + err * x(n-N+1)
  555.         STF     R2,*AR1++(1)%      ; update last w
  556.  
  557. ;   Define constants
  558. xn      .usect  "buffer",order3
  559. wn      .usect  "coeffs",order3
  560.         .data
  561. C40addr1    .word   C40_3_1
  562. C40addr2    .word   C40_3_2
  563. C40addr4    .word   C40_3_4
  564. xn_addr     .word   xn
  565. wn_addr     .word   wn
  566.         .end
  567.  
  568.  
  569. [LISTING NINE]
  570.  
  571. ******************************************************************
  572. *    LMS4 :  Cascade TMS320C40 adaptive filter #4 Using Transversal
  573. *        Structure and LMS Algorithm, Looped Code
  574. *  Configuration:
  575. *        d(n) --------------------------+
  576. *                       |
  577. *               e(n)        |+
  578. *                 +-----<-----(SUM)
  579. *                 |         |-
  580. *             --------+--------     |
  581. *        x(n) ----|Adaptive Filter|-----+--------> y(n)
  582. *             -----------------
  583. *         +--------<-------+-------<--------+-------<--------+
  584. *         |        |y2(n)       |y3(n)       |y4(n)
  585. *   y(n)<-+   |        |            |            |
  586. *     |  +----+----+      +----+----+      +----+----+  +----+----+
  587. *     +--|TMS320C40|x(n1) |TMS320C40|x(n2) |TMS320C40|x(n3) |TMS320C40|
  588. *   x(n)---->|         |----->|     |----->|     |----->|     |
  589. *     +->|   # 1   |      |   # 2   |      |   # 3   |  |   # 4   |
  590. *     |  +----+----+      +----+----+      +----+----+  +----+----+
  591. *   d(n)--+   |        |            |            |
  592. *         e(n)|        |            |            |
  593. *         +-------->-------+------->--------+------->--------+
  594. *         where n1 = n-N1, n2 = n-N1-N2, and n3 = n-N1-N2-N3
  595. *  Algorithm for processor #4:
  596. *        N4-1
  597. *    y4(n) = SUM w(N1+N2+N3+k)*x(n-N1-N2-N3-k)   k=0,1,2,...,N4-1
  598. *        k=0
  599. *    w(N1+N2+N3+k) = w(N1+N2+N3+k) + u*e(n)*x(n-N1-N2-N3-k) k=0,1,2,...,N4-1
  600. *    where filter order N = N1 + N2 + N3 + N4 and u is the step size mu.
  601. **********************************************************************
  602.         .include "const.h"         ; include the constant definition file
  603.         .sect    "vector"
  604. reset       .word     begin
  605. ;   Initialize pointers and arrays
  606. ;     xptr = &x[0];
  607. ;     wptr = &w[0];
  608. ;     for (i=0;i<N4;i++){
  609. ;     *xptr++ = 0.0;
  610. ;     *wptr++ = 0.0;
  611. ;     }
  612.         .text
  613. begin       .set    $
  614.         LDP     @C40addr1          ; set data page
  615.         LDI     0,R2           ; R2 = 0
  616.         LDF     0.0,R1         ; R1 = 0.0
  617.         LDI     @C40addr1,AR5      ; set pointer for #1 C40 comm port
  618.         LDI     @C40addr2,AR6      ; set pointer for #2 C40 comm port
  619.         LDI     @C40addr3,AR7      ; set pointer for #3 C40 comm port
  620.         LDI     @xn_addr,AR0       ; set pointer for x[]
  621.         LDI     @wn_addr,AR1       ; set pointer for w[]
  622.         STI     R2,*-AR5(1)        ; enable #1 C40 comm port
  623.         STI     R2,*-AR6(1)        ; enable #2 C40 comm port
  624.         STI     R2,*-AR7(1)        ; enable #3 C40 comm port
  625.         RPTS    order4-1
  626.         STF     R1,*AR0++(1)%      ; x[] = 0.
  627.     ||  STF     R1,*AR1++(1)%      ; w[] = 0.
  628.         LDI     order4,BK          ; set up circular buffer
  629. input:
  630. ;   Compute filter output y(n)
  631. ;     xptr = &x[0];
  632. ;     wptr = &w[0];
  633. ;     receive(x);          /* receive x(n-N1-N2-N3) from processor #3 */
  634. ;     *xptr = x;
  635. ;     for (i=0;i<N4;i++)
  636. ;     y4 += *xptr++ * *wptr++;
  637.         LDI     order4-2,RC
  638.         RPTBD   filter
  639.         LDF     *AR7,R6        ; input x(n)
  640.         STF     R6,*AR0        ; insert x(n) to buffer
  641.         MPYF3   *AR0++(1)%,*AR1++(1)%,R1
  642.     ||  SUBF3   R2,R2,R2           ; R2 = 0.0
  643. filter      MPYF3   *AR0++(1)%,*AR1++(1)%,R1
  644.     ||  ADDF3   R1,R2,R2           ; y4(n) = w[].x[]
  645.         ADDF    R1,R2          ; include last result
  646. ;   Output y4(n) signals
  647. ;     pass(y4);           /* pass y4 to processor #1 */
  648.         STF     R2,*+AR5(1)        ; send y4(n) to #1 C40
  649. ;   Input error signal e(n)
  650. ;     receive(e);         /* receive e(n) form processor #1 */
  651.         LDF     *AR5,R7        ; load e(n) from #1 C40
  652. ;   Update weights w(n)
  653. ;     xptr = &x[N4-1];
  654. ;     wptr = &w[N4-1];
  655. ;     for (i=N3;i>0;i--){
  656. ;     *wptr-- += mu * e *xptr--;
  657. ;     *(xptr+1) = *xptr;      /* delayed tap is implemented
  658. ;                    in circular buffer      */
  659. ;     }
  660.         LDI     order4-3,RC        ; initialize repeat counter
  661.         RPTBD   weight         ; do i = 0, N4-3
  662.         MPYF3   R7,*AR0++(1)%,R1   ; R1 = err * x(n)
  663.         ADDF3   R1,*AR1,R2         ; R2 = wi(n) + err * x(n)
  664.         NOP
  665.  
  666.         MPYF3   R7,*AR0++(1)%,R1   ; R1 = err * x(n-i-1)
  667.     ||  STF     R2,*AR1++(1)%      ; update wi(n+1)
  668. weight      ADDF3   R1,*AR1,R2         ; R2 = wi(n) + err * x(n-i)
  669.  
  670.         BD      input          ; delay branch
  671.         MPYF3   R7,*AR0,R1         ; R1 = err * x(n-N+1)
  672.     ||  STF     R2,*AR1++(1)%      ; update wi(n+1)
  673.         ADDF3   R1,*AR1,R2         ; R2 = wi(n-N+1) + err * x(n-N+1)
  674.         STF     R2,*AR1++(1)%      ; update last w
  675.  
  676. ;   Define constants
  677. xn      .usect  "buffer",order4
  678. wn      .usect  "coeffs",order4
  679.         .data
  680. C40addr1    .word   C40_4_1
  681. C40addr2    .word   C40_4_2
  682. C40addr3    .word   C40_4_3
  683. xn_addr     .word   xn
  684. wn_addr     .word   wn
  685.         .end
  686.  
  687.